package com.fowo.api.datainterface.service.impl.implCore;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.fowo.api.datainterface.aspect.BaseAspect;
import com.fowo.api.datainterface.constants.Constants;
import com.fowo.api.datainterface.constants.DataTypeKind;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.model.DataContextModel;
import com.fowo.api.datainterface.service.serviceCore.BaseFromService;
import com.fowo.api.datainterface.service.serviceCore.BaseInvokeService;
import com.fowo.api.datainterface.util.Common;
import com.fowo.api.datainterface.util.JScriptUtil;
import com.fowo.api.datainterface.util.JsonUtil;
import com.fowo.api.datainterface.util.RestUtilK3Cloud;
import com.fowo.api.datainterface.util.k3cloud.domain.Authentication;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据接口 服务实现类
 */
@Service
@Slf4j
@DS("ds24")
@RequiredArgsConstructor
public class K3cloudServiceImpl implements BaseInvokeService, BaseFromService {

    private final Common common;

    private volatile BaseAspect baseAspect;

    public synchronized BaseAspect getBaseAspect(String type) {
        return ObjUtil.isEmpty(baseAspect) ? new BaseAspect(type) : baseAspect;
    }

    private final JScriptUtil jScriptUtil;

    @Override
    public DataTypeKind getType() {
        return DataTypeKind.K3cloud;
    }

    @Override
    public Object getAuth(DataContextModel.DatainterfaceAuthorityModel authority) {
        String actId = common.getAuthoritySimpleFactory(authority, "actId");
        String username = common.getAuthoritySimpleFactory(authority, "username");
        String password = common.getAuthoritySimpleFactory(authority, "password");
        return new Authentication(actId, username, password);
    }


    /**
     * 直接执行
     * @param authority
     * @param formId  接口方法
     * @param requestMethod Query、Save
     * @param object 参数
     * @return
     */
    public Object invokeNative(DatainterfaceAuthority authority, String formId, String requestMethod, String object) {
        Assert.isTrue(ObjectUtil.isNotEmpty(authority) && StrUtil.isAllNotBlank(formId, requestMethod) && ObjectUtil.isNotEmpty(object), "参数校验不通过！");
        Object res = null;
        try {
            IdentifyInfo auth =new IdentifyInfo();
            auth.setUserName(common.getAuthoritySimpleFactory(authority, "username"));
            auth.setdCID(common.getAuthoritySimpleFactory(authority, "actId"));
            auth.setAppId(common.getAuthoritySimpleFactory(authority, "appId"));
            auth.setPwd(common.getAuthoritySimpleFactory(authority, "password"));
            auth.setAppSecret(common.getAuthoritySimpleFactory(authority, "appSecret"));
            auth.setlCID(Convert.toInt(common.getAuthoritySimpleFactory(authority, "CID"),2052));
            auth.setServerUrl(authority.getRootPath());
            res = getBaseAspect(authority.getAppName()).k3cloudrequest(auth, formId, requestMethod, object, Constants.Write,StrUtil.EMPTY);

        } catch (Exception ex) {
            throw new RuntimeException(StrUtil.format(" 金蝶执行 {} 参数 {} 发生异常 ", formId, StrUtil.subPre(JsonUtil.getObjectToString(object), 500), ExceptionUtil.getRootCauseMessage(ex)));
        }
        return res;
    }
    @Override
    public Object invokeFrom(DataContextModel.DatainterfaceFromModel from, JSONObject currentParamsMap, JSONObject currentHeadersMap) {
        DataContextModel.DatainterfaceAuthorityModel authority = from.getAuthority();
        Assert.isTrue(ObjectUtil.isAllNotEmpty(authority), "接口 {} 金蝶授权信息配置错误，请检查配置", StrUtil.concat(true, from.getEnCode()));
        String rootPath = authority.getRootPath();
        String formId = from.getInterfaceUrl();
        Authentication auth = Convert.convertQuietly(Authentication.class, getAuth(authority)); //CrmApiSign.getSign(jsonObject, invoke.getAuthority());
        Assert.isTrue(BeanUtil.isNotEmpty(auth), "{} 来源接口 {} 请配置授权格式,例: {\"actId\":\"\",\"username\":\"\",\"password\":\"\"}", StrUtil.concat(true, from.getTaskCode()), from.getEnCode());
        String requestMethod = from.getRequestMethod();
        String requestParams = from.getRequestParams();
        // 请求拼接参数
        JSONObject jsonObject = null;
        Object res = null;
        if (HttpUtil.isHttp(rootPath) || HttpUtil.isHttps(rootPath)) {
            //请求参数解析
            List<JSONObject> requestParamsListMap = JsonUtil.getJsonToList(requestParams);
            jsonObject = common.processBodyArgs(currentParamsMap, jsonObject, requestParamsListMap);
            if (MapUtil.isEmpty(jsonObject)) {
                Assert.isTrue(false, "{} 来源接口 {} 未指定任何参数，请检查", StrUtil.concat(true, from.getTaskCode()), from.getEnCode());
            }
            try {
                res = getBaseAspect(from.getAuthority().getAppName()).k3cloudrequest(rootPath, auth, formId, requestMethod, jsonObject, Constants.Write,StrUtil.EMPTY);
            } catch (Exception ex) {
                throw new RuntimeException(StrUtil.format("{} 金蝶来源接口 {} ，执行 {} 操作 {} 发生异常 ", StrUtil.concat(true, from.getTaskCode()), from.getEnCode(), formId, StrUtil.subPre(JsonUtil.getObjectToString(jsonObject), 500), ExceptionUtil.getRootCauseMessage(ex)));
            }
            String jsonToBean = JsonUtil.getJsonToBeanSafe(res, "[0][0].Result.ResponseStatus.IsSuccess", String.class);
            if (StrUtil.isNotEmpty(jsonToBean) && StrUtil.equalsIgnoreCase("false", jsonToBean)) {
                throw new RuntimeException(StrUtil.concat(true, "拉取失败或无返回值：", StrUtil.subPre(JsonUtil.getObjectToString(res), 500)));
            }
        } else {
            Assert.isTrue(false, "{} 来源接口 {} 指定的查询 {} 类型错误！", StrUtil.concat(true, from.getTaskCode()), from.getEnCode(), requestMethod);
        }
        return jScriptUtil.callJsFrom(from.getDataProcessing(), res == null ? new ArrayList<>() : res, null, null);
    }


}
